﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Sharp.Compiler.CSharp
{
    public struct LexiconBoundaryPoint
    {
        public int Start, End, Type, SubType;
    };
    class Lexicon
    {
        /*
         * Issues:
         * the '*' operator is colliding with delimeted line comment
         * Does not detect the end hex integer values
         * nor floats or doubles
         */ 
        public Lexicon()
        {
            LBP = new List<LexiconBoundaryPoint>();
        }
        public void Analyse(string text)
        {
            /* The code is split into a list of Lexicon Boundary Points.
             * This is used later by the syntax analyser.
             * Initialise the first boundary
             */
            LexiconBoundaryPoint boundary = new LexiconBoundaryPoint();
            boundary.Start = -1;
            boundary.End = -1;
            boundary.Type = 0;
            boundary.SubType = 0;
            /*
             * In Case the index of Lexicon Boundary Point Changes
             * We should check the indexes. This makes our code clearer to read
             * and it is more efficient to compare an integer instead of
             * a string.
             */
            int Error = WhatTypeIs("Error");
            int Unsupported = WhatTypeIs("Unsupported");
            int Comment = WhatTypeIs("Comment");
            int CommentSingleLine = WhatTypeIs("CommentSingleLine");
            int CommentDelimetedLine = WhatTypeIs("CommentDelimitedLine");
            int WhiteSpace = WhatTypeIs("WhiteSpace");
            int WhiteSpaceLineTerminator = WhatTypeIs("WhiteSpaceLineEnding");
            int PreProcessorDirective = WhatTypeIs("PreProcessorDirective");
            int Punctuator = WhatTypeIs("Punctuator");
            int PunctuatorCodeBlockStart = WhatTypeIs("PunctuatorCodeBlockStart");
            int PunctuatorCodeBlockEnd = WhatTypeIs("PunctuatorCodeBlockEnd");
            int PunctuatorBracketStart = WhatTypeIs("PunctuatorBracketStart");
            int PunctuatorBracketEnd = WhatTypeIs("PunctuatorBracketEnd");
            int PunctuatorSquareBracketStart = WhatTypeIs("PunctuatorSquareBracketStart");
            int PunctuatorSquareBracketEnd = WhatTypeIs("PunctuatorSquareBracketEnd");
            int PunctuatorComma = WhatTypeIs("PunctuatorComma");
            int PunctuatorAccessor = WhatTypeIs("PunctuatorAccessor");
            int PunctuatorColon = WhatTypeIs("PunctuatorColon");
            int PunctuatorColonColon = WhatTypeIs("PunctuatorColonColon");
            int PunctuatorSemicolon = WhatTypeIs("PunctuatorSemicolon");
            int Operator = WhatTypeIs("Operator");
            int OperatorEquallity = WhatTypeIs("OperatorEquallity");
            int OperatorAssignment = WhatTypeIs("OperatorAssignment");
            int OperatorRelational = WhatTypeIs("OperatorRelational");
            int OperatorIncremental = WhatTypeIs("OperatorIncremental");
            int OperatorConditional = WhatTypeIs("OperatorConditional");
            int OperatorLogical = WhatTypeIs("OperatorLogical");
            int OperatorShift = WhatTypeIs("OperatorShift");
            int OperatorUnary = WhatTypeIs("OperatorUnary");
            int OperatorBitwise = WhatTypeIs("OperatorBitwise");
            int OperatorLambda = WhatTypeIs("OperatorLambda");
            int OperatorMultiplicative = WhatTypeIs("OperatorMultiplicative");
            int OperatorAddition = WhatTypeIs("OperatorAddition");
            int Literal = WhatTypeIs("Literal");
            int LiteralString = WhatTypeIs("LiteralString");
            int LiteralCharacter = WhatTypeIs("LiteralCharacter");
            int LiteralNumeric = WhatTypeIs("LiteralNumeric");
            int LiteralIntegerDecimal = WhatTypeIs("LiteralIntegerDecimal");
            int LiteralIntegerHexidecimal = WhatTypeIs("LiteralIntegerHexidecimal");
            int LiteralReal = WhatTypeIs("LiteralReal");
            int LiteralRealFloat= WhatTypeIs("LiteralRealFloat");
            int LiteralRealDouble = WhatTypeIs("LiteralRealDouble");
            int LiteralRealDecimal = WhatTypeIs("LiteralRealDecimal");
            int Keyword = WhatTypeIs("Keyword");
            int KeywordTypesBuiltIn = WhatTypeIs("KeywordTypesBuiltIn");
            int KeywordTypesReferences = WhatTypeIs("KeywordTypesReferences");
            int KeywordTypeless = WhatTypeIs("KeywordTypeless");
            int KeywordModifiers = WhatTypeIs("KeywordModifiers");
            int KeywordStatementSelection = WhatTypeIs("KeywordStatementSelection");
            int KeywordStatementIteration = WhatTypeIs("KeywordStatementIteration");
            int KeywordStatementJump = WhatTypeIs("KeywordStatementJump");
            int KeywordStatementException = WhatTypeIs("KeywordStatementException");
            int KeywordStatementChecked = WhatTypeIs("KeywordStatementChecked");
            int KeywordStatementFixed = WhatTypeIs("KeywordStatementFixed");
            int KeywordStatementLock = WhatTypeIs("KeywordStatementLock");
            int KeywordMethodParameters = WhatTypeIs("KeywordMethodParameters");
            int KeywordNamespace = WhatTypeIs("KeywordNamespace");
            int KeywordOperators = WhatTypeIs("KeywordOperators");
            int KeywordConversion = WhatTypeIs("KeywordConversion");
            int KeywordAccess = WhatTypeIs("KeywordAccess");
            int KeywordLiteral = WhatTypeIs("KeywordLiteral");
            int KeywordContextual = WhatTypeIs("KeywordContextual");
            int KeywordAcesssModifier = WhatTypeIs("KeywordAcesssModifier");
            int Identifier = WhatTypeIs("Identifier");
            // For keyword detection
            string Token = "";
            // Scan through the source code text
            for (int i = 0; i < text.Length; i++)
            {
                // Make sure that we have a new boundary
                #region Find Comments
                if (text[i] == '/' &&
                    boundary.Start == -1)
                {
                    /*
                     * watch out: '/' could be a punctuator.
                     * Protect against invalid index access.
                     */ 
                    if (text.Length > i + 1)
                    {
                        if (text[i + 1] == '/')
                        {
                            // It's the start Single line or XML comment
                            boundary.Start = i;
                            boundary.Type = Comment;
                            boundary.SubType = CommentSingleLine;
                        }
                        else if (text[i + 1] == '*')
                        {
                            // Start of a Delimeted line comment
                            boundary.Start = i;
                            boundary.Type = Comment;
                            boundary.SubType = CommentDelimetedLine;
                        }
                    }

                }
                // Find Delimeted line comment ending
                if (text[i] == '*' &&
                    boundary.Start != -1 &&
                    boundary.Type == Comment &&
                    boundary.SubType == CommentDelimetedLine)
                {
                    if (text.Length > i + 1)
                    {
                        if (text[i + 1] == '/')
                        {
                            // End of a Delimeted line comment
                            boundary.End = i + 1;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = -1;
                            boundary.End = -1;
                            boundary.Type = 0;
                            boundary.SubType = 0;
                            i++;
                            continue; // Next character
                        }
                    }
                }
                // if Single line then find the end of the line
                if (boundary.Type == Comment &&
                    boundary.SubType == CommentSingleLine &&
                    text[i] == '\u000A') // LineFeed (LF)
                {
                    /*
                     * End of a Single line comment
                     * Add line ending to LBP and move i to boundary.end + 1
                     */ 
                    if (text.Length > 0)
                    {
                        if (text[i - 1] == '\u000D') // CR LF (Windows)
                        {
                            boundary.End = i - 2;
                            LBP.Add(boundary);
                        }
                        else // Unix
                        {
                            boundary.End = i - 1;
                            LBP.Add(boundary);
                        }
                    }
                    // Create new boundary
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = -1;
                    boundary.End = -1;
                    boundary.Type = 0;
                    boundary.SubType = 0;
                    continue; // Next character
                }
                #endregion
                #region Find Pre-Processor Directives
                // Make sure that we have a new boundary
                if (text[i] == '#' &&
                    boundary.Start == -1)
                {
                    // find the line feed
                    boundary.Start = i;
                    boundary.Type = PreProcessorDirective;
                    boundary.SubType = Unsupported;
                }
                else if (boundary.Type == PreProcessorDirective &&
                         text[i] == '\u000A') // LineFeed (LF)
                {
                    // Add line ending to LBP and move i to boundary.end + 1
                    if (text.Length > 0)
                    {
                        if (text[i - 1] == '\u000D') // CR LF (Windows)
                        {
                            // End of PreProcessorDirective
                            boundary.End = i - 2;
                            LBP.Add(boundary);
                        }
                        else // Unix
                        {
                            // End of PreProcessorDirective
                            boundary.End = i - 1;
                            LBP.Add(boundary);
                        }
                    }
                    // Create new boundary
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = -1;
                    boundary.End = -1;
                    boundary.Type = 0;
                    boundary.SubType = 0;
                    continue; // Next Character
                }
                #endregion
                #region Find Punctuators
                if (boundary.Start == -1 &&
                    text[i] == '{')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorCodeBlockStart;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue;
                }
                else if (boundary.Start == -1 &&
                         text[i] == '}')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorCodeBlockEnd;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '(')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorBracketStart;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == ')')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorBracketEnd;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == ',')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorComma;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == ';')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorSemicolon;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == ':')
                {
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == ':')
                        {
                            boundary.Start = i;
                            boundary.End = i;
                            boundary.Type = Punctuator;
                            boundary.SubType = PunctuatorColonColon;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorColon;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '[')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorSquareBracketStart;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == ']')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorSquareBracketEnd;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '.')
                {
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Punctuator;
                    boundary.SubType = PunctuatorAccessor;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                        text[i] == '-')
                {
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '>')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Punctuator;
                            boundary.SubType = PunctuatorAccessor;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                }
                #endregion
                #region Find Literals
                // This must be done before operators to prevent
                // collisions.
                if (boundary.Start == -1 &&
                    boundary.Type != Comment &&
                    text[i] == '"')
                {
                    boundary.Start = i;
                    boundary.Type = Literal;
                    boundary.SubType = LiteralString;
                    continue; // Next Character
                }
                if (boundary.SubType == LiteralString &&
                    text[i] == '"')
                {
                    // check for '\"'
                    if (i > 0)
                    {
                        if (text[i - 1] == '\\')
                        {
                            continue; // Next Character
                        }
                    }
                    boundary.End = i;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                if (boundary.Start == -1 &&
                    boundary.Type != Comment &&
                    text[i] == '\'')
                {
                    // check for '\"'
                    if (i > 0)
                    {
                        if (text[i - 1] == '\\')
                        {
                            continue; // Next Character
                        }
                    }
                    boundary.Start = i;
                    boundary.Type = Literal;
                    boundary.SubType = LiteralCharacter;
                    continue; // Next Character
                }
                // Char channot contain new line character:
                if (boundary.SubType == LiteralCharacter && 
                    text[i] == '\n')
                {
                    boundary.Type = Error;
                    continue; // Next Character
                }
                if (boundary.SubType == LiteralCharacter &&
                   text[i] == '\'')
                {
                    // check for '\"'
                    if (i > 0)
                    {
                        if (text[i - 1] == '\\')
                        {
                            continue; // Next Character
                        }
                    }
                    boundary.End = i;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                // numeric literal
                if (boundary.Start == -1 &&
                    text[i] >= 0x30 &&
                    text[i] <= 0x39)
                {
                    boundary.Start = i;
                    boundary.Type = Literal;
                    // Intermediate state, to assist 
                    boundary.SubType = LiteralNumeric;
                    // Check hex prefix
                    if (i + 1 < text.Length)
                    {
                        if (text[i] == '0' &&
                            (text[i + 1] == 'x' ||
                            text[i + 1] == 'X'
                            )
                        )
                        {
                            boundary.SubType = LiteralIntegerHexidecimal;
                        }
                    }
                    continue; // Next Character
                }
                if (boundary.Type == Literal &&
                    boundary.SubType == LiteralIntegerHexidecimal)
                {
                    // Find the end of the hex value
                    // Find suffix (very long code)
                    if(text[i] == 'u' ||
                        text[i] == 'U')
                    {
                        if (i + 1 < text.Length)
                        {
                            if (text[i + 1] == 'l' ||
                                text[i + 1] == 'L')
                            {
                                boundary.End = i + 1;
                                LBP.Add(boundary);
                                i++;
                                boundary = new LexiconBoundaryPoint();
                                boundary.Start = boundary.End = -1;
                                boundary.SubType = boundary.Type = 0;
                                continue; // Next Character
                            }
                        }
                        boundary.End = i;
                        LBP.Add(boundary);
                        boundary = new LexiconBoundaryPoint();
                        boundary.Start = boundary.End = -1;
                        boundary.SubType = boundary.Type = 0;
                        continue; // Next Character
                    }
                    else if (text[i] == 'l' ||
                            text[i] == 'L')
                    {
                        if (i + 1 < text.Length)
                        {
                            if (text[i + 1] == 'u' ||
                                text[i + 1] == 'U'
                                )
                            {
                                boundary.End = i + 1;
                                LBP.Add(boundary);
                                i++;
                                boundary = new LexiconBoundaryPoint();
                                boundary.Start = boundary.End = -1;
                                boundary.SubType = boundary.Type = 0;
                                continue; // Next Character
                            }
                        }
                        boundary.End = i;
                        LBP.Add(boundary);
                        boundary = new LexiconBoundaryPoint();
                        boundary.Start = boundary.End = -1;
                        boundary.SubType = boundary.Type = 0;
                        continue; // Next Character
                    }
                    //
                    // find a non hex digit
                    if ((text[i] <= 0x30 && // not 0-9
                        text[i] >= 0x39) ||
                        (text[i] <= 0x41 && // A - F
                        text[i] >= 0x46) ||
                        (text[i] <= 0x61 && // a -f
                        text[i] >= 0x66))
                    {
                        boundary.End = i - 1;
                        LBP.Add(boundary);
                        boundary = new LexiconBoundaryPoint();
                        boundary.Start = boundary.End = -1;
                        boundary.SubType = boundary.Type = 0;
                        continue; // Next Character
                    }

                }
                if((boundary.Type == Literal) &&
                    boundary.SubType == LiteralNumeric ||
                    boundary.SubType == LiteralReal)
                {
                    // Watch out for colisions with identifiers and operators
                    // Work out what type of numeric literal
                    if ( text[i] < 0x30 ||
                    text[i] > 0x39
                    )
                    {
                        // IF text[i] is not a numeric character:
                        // Is it a real number
                        if (text[i] == '.')
                        {
                            boundary.SubType = LiteralReal;
                            continue;
                        }
                        // What type of real number
                        if (text[i] == 'f' ||
                                 text[i] == 'F')
                        {
                            boundary.SubType = LiteralRealFloat;
                            boundary.End = i;
                        }
                        else if (text[i] == 'D' ||
                                 text[i] == 'd')
                        {
                            boundary.SubType = LiteralRealDouble;
                            boundary.End = i;
                        }
                        else if (text[i] == 'M' ||
                                 text[i] == 'm')
                        {
                            boundary.SubType = LiteralRealDecimal;
                            boundary.End = i;
                        }
                        // Is it a decimal integer number.
                        else if (boundary.SubType != LiteralReal &&
                            boundary.SubType != LiteralRealFloat &&
                            boundary.SubType != LiteralRealDouble &&
                            boundary.SubType != LiteralRealDecimal)
                        {
                            boundary.SubType = LiteralIntegerDecimal;
                            // Find suffix (very long code)
                            if (text[i] == 'u' ||
                                text[i] == 'U')
                            {
                                if (i + 1 < text.Length)
                                {
                                    if (text[i + 1] == 'l' ||
                                        text[i + 1] == 'L')
                                    {
                                        boundary.End = i + 1;
                                    }
                                }
                                boundary.End = i;
                            }
                            else if (text[i] == 'l' ||
                                    text[i] == 'L')
                            {
                                if (i + 1 < text.Length)
                                {
                                    if (text[i + 1] == 'u' ||
                                        text[i + 1] == 'U'
                                        )
                                    {
                                        boundary.End = i + 1;
                                    }
                                }
                                boundary.End = i;
                            }
                            else
                            {
                                boundary.End = i - 1;
                                i--;
                            }
                        }
                        else
                        {
                            boundary.SubType = LiteralRealDouble;
                            boundary.End = i-1;
                            i--;
                        }
                        //
                        boundary.Type = Literal; // Force Type
                        LBP.Add(boundary);
                        boundary = new LexiconBoundaryPoint();
                        boundary.Start = boundary.End = -1;
                        boundary.SubType = boundary.Type = 0;
                        continue; // Next Character
                    }
                    
                }
                #endregion
                #region Finding Operators
                if (boundary.Start == -1 && text[i] == '*')
                {
                    // Combinations eg *=
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            // on its own
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorAssignment;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // preven collision with comments
                    if (boundary.Type != Comment)
                    {
                        // on its own
                        boundary.Start = i;
                        boundary.End = i;
                        boundary.Type = Operator;
                        boundary.SubType = OperatorMultiplicative;
                        LBP.Add(boundary);
                    }
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                    
                }
                else if (boundary.Start == -1 &&
                         text[i] == '/')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            // on its own
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorAssignment;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorMultiplicative;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '+')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorAssignment;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        else if (text[i + 1] == '+')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorIncremental;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorAddition;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '-')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorAssignment;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        else if (text[i + 1] == '+')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorIncremental;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorAddition;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '<')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorRelational;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        if (text[i + 1] == '<')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorShift;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        if (i + 2 < text.Length)
                        {
                            if (text[i + 1] == '<' &&
                                text[i + 2] == '=')
                            {
                                boundary.Start = i;
                                boundary.End = i + 1;
                                boundary.Type = Operator;
                                boundary.SubType = OperatorAssignment;
                                LBP.Add(boundary);
                                boundary = new LexiconBoundaryPoint();
                                boundary.Start = boundary.End = -1;
                                boundary.SubType = boundary.Type = 0;
                                i++; i++;
                                continue; // Next Character
                            }
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorRelational;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '>')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorRelational;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        if (text[i + 1] == '>')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorShift;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        if (i + 2 < text.Length)
                        {
                            if (text[i + 1] == '>' &&
                                text[i + 2] == '=')
                            {
                                boundary.Start = i;
                                boundary.End = i + 1;
                                boundary.Type = Operator;
                                boundary.SubType = OperatorAssignment;
                                LBP.Add(boundary);
                                boundary = new LexiconBoundaryPoint();
                                boundary.Start = boundary.End = -1;
                                boundary.SubType = boundary.Type = 0;
                                i++; i++;
                                continue; // Next Character
                            }
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorRelational;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '&')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorAssignment;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        else if (text[i + 1] == '&')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorConditional;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorLogical;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '|')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorAssignment;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        else if (text[i + 1] == '|')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorLogical;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorConditional;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '^')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorAssignment;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorLogical;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '?')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '?')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorConditional;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorConditional;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '!')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorEquallity;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorUnary;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                    text[i] == '%')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorAssignment;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorMultiplicative;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '~')
                { 
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorUnary;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                else if (boundary.Start == -1 &&
                         text[i] == '=')
                {
                    // Combinations
                    if (i + 1 < text.Length)
                    {
                        if (text[i+1] == '=')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorEquallity;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                        else if (text[i + 1] == '>')
                        {
                            boundary.Start = i;
                            boundary.End = i + 1;
                            boundary.Type = Operator;
                            boundary.SubType = OperatorLambda;
                            LBP.Add(boundary);
                            boundary = new LexiconBoundaryPoint();
                            boundary.Start = boundary.End = -1;
                            boundary.SubType = boundary.Type = 0;
                            i++;
                            continue; // Next Character
                        }
                    }
                    // on its own
                    boundary.Start = i;
                    boundary.End = i;
                    boundary.Type = Operator;
                    boundary.SubType = OperatorEquallity;
                    LBP.Add(boundary);
                    boundary = new LexiconBoundaryPoint();
                    boundary.Start = boundary.End = -1;
                    boundary.SubType = boundary.Type = 0;
                    continue; // Next Character
                }
                #endregion
                #region Find Keywords and Identifiers
                /*
                 * Identifiers: @if myDog1 _myDog1 
                 * Keywords are reserved identifiers
                 */ 
                if (boundary.Start == -1)
                {
                    // Is Underscore
                    if (text[i] == '_')
                    {
                        boundary.Start = i;
                        boundary.Type = Identifier;
                        boundary.SubType = Identifier;
                        continue; // Next character
                    }
                    // Is @ prefix
                    if (text[i] == '@')
                    {
                        boundary.Start = i;
                        boundary.Type = Identifier;
                        boundary.SubType = Identifier;
                        continue; // Next character
                    }
                    // Is whitespace,
                    if (text[i] <= 0x20)
                    {
                        continue; // Next character
                    }
                    else if (text[i] == 0x0085 || // NextLine
                             text[i] == 0x00A1 || // No-break space
                             text[i] == 0x180E) // Mongolian vowel separator)
                    {
                        continue; // Next character
                    }
                    else if (text[i] >= 0x2000 && // Spaces
                                text[i] <= 0x200A)
                    {
                        continue; // Next character
                    }
                    else if (text[i] == 0x2028 || // Line separator
                                text[i] == 0x2029) // paragraph separator
                    {
                        continue; // Next character
                    }
                    else if (text[i] == 0x202F) // narrow no-break space
                    {
                        continue; // Next character
                    }
                    else if (text[i] == 0x205F) // ideographic space
                    {
                        continue; // Next character
                    }
                    boundary.Start = i;
                    boundary.Type = Identifier;
                    boundary.SubType = Identifier;
                    continue; // Next character
                }
                if (boundary.Start != -1 &&
                    boundary.Type == Identifier)
                {
                    // Find the end of Identifier Or Keyword
                    /*
                     * It should not contain any whiteshace
                     * i - 1;
                     */ 
                    // Is Whitespace
                    if (text[i] <= 0x20)
                    {
                            boundary.End = i - 1;
                    }
                    else if (text[i] == 0x0085 || // NextLine
                             text[i] == 0x00A1 || // No-break space
                             text[i] == 0x180E) // Mongolian vowel separator)
                    {
                        boundary.End = i - 1;
                    }
                    else if (text[i] >= 0x2000 && // Spaces
                                text[i] <= 0x200A)
                    {
                        boundary.End = i - 1;
                    }
                    else if (text[i] == 0x2028 || // Line separator
                                text[i] == 0x2029) // paragraph separator
                    {
                        boundary.End = i - 1;
                    }
                    else if (text[i] == 0x202F) // narrow no-break space
                    {
                        boundary.End = i - 1;
                    }
                    else if (text[i] == 0x205F) // ideographic space
                    {
                        boundary.End = i - 1; 
                    }
                    /*
                     * if we find and punctuator or operator we need to make 
                     * sure that the we can reconise what they are. If a 
                     * boundary.start is not -1. then  it will not. So...
                     * 
                     * boundary.End = i - 1;
                     * i--;
                     * 
                     * ...must be used. boundary.End must not include operators
                     * or punctuators. 'i' must be de in-cremented and the new
                     * Boundary must be created to ensure that the character is
                     * detected correctly.
                     * 
                     */
                    // Is Puncuation or Operators
                    else if (text[i] >= 0x0021 &&
                                text[i] <= 0x002F)
                    {
                        boundary.End = i - 1;
                        i--;
                    }
                    else if (text[i] >= 0x003A &&
                            text[i] <= 0x0040)
                    {
                        boundary.End = i - 1;
                        i--;
                    }
                    else if (text[i] >= 0x005B &&
                                text[i] <= 0x005E)
                    {
                        boundary.End = i - 1;
                        i--;
                    }
                    else if (text[i] == 0x0060)
                    {
                        boundary.End = i - 1;
                        i--;
                    }
                    else if (text[i] >= 0x007B &&
                                text[i] <= 0x00BF)
                    {
                        boundary.End = i - 1;
                        i--;
                    }
                    else if (text[i] >= 0x02B9 &&
                                text[i] <= 0x02FE)
                    {
                        boundary.End = i - 1;
                        i--;
                    }
                    if (boundary.End >= 0)
                    {
                        // Is Keyword
                        if (text[boundary.Start] != '_' &&
                            text[boundary.Start] != '@')
                        {
                            Token = text.Substring(boundary.Start,
                                           (boundary.End - boundary.Start) +1);
                            Token += "";
                            for (int ii = 0; ii < mKeywords.Length; ii++)
                            {
                                if (Token == mKeywords[ii])
                                {
                                    boundary.Type = Keyword;
                                    // What is the sub type?
                                    if (ii >= 0 && ii <= 13)
                                    {
                                        boundary.SubType = KeywordTypesBuiltIn;
                                    }
                                    else if (ii >= 14 && ii <= 19)
                                    {
                                        boundary.SubType = KeywordTypesReferences;
                                    }
                                    else if (ii == 20)
                                    {
                                        boundary.SubType = KeywordTypeless;
                                    }
                                    else if (ii >= 21 && ii <= 31)
                                    {
                                        boundary.SubType = KeywordModifiers;
                                    }
                                    else if (ii >= 32 && ii <= 35)
                                    {
                                        boundary.SubType = KeywordStatementSelection;
                                    }
                                    else if (ii >= 36 && ii <= 40)
                                    {
                                        boundary.SubType = KeywordStatementIteration;
                                    }
                                    else if (ii >= 41 && ii <= 44)
                                    {
                                        boundary.SubType = KeywordStatementJump;
                                    }
                                    else if (ii >= 45 && ii <= 48)
                                    {
                                        boundary.SubType = KeywordStatementException;
                                    }
                                    else if (ii >= 49 && ii <= 50)
                                    {
                                        boundary.SubType = KeywordStatementChecked;
                                    }
                                    else if (ii == 51)
                                    {
                                        boundary.SubType = KeywordStatementFixed;
                                    }
                                    else if (ii == 52)
                                    {
                                        boundary.SubType = KeywordStatementLock;
                                    }
                                    else if (ii >= 53 && ii <= 55)
                                    {
                                        boundary.SubType = KeywordMethodParameters;
                                    }
                                    else if (ii >= 56 && ii <= 58)
                                    {
                                        boundary.SubType = KeywordNamespace;
                                    }
                                    else if (ii >= 59 && ii <= 64)
                                    {
                                        boundary.SubType = KeywordOperators;
                                    }
                                    else if (ii >= 65 && ii <= 67)
                                    {
                                        boundary.SubType = KeywordConversion;
                                    }
                                    else if (ii >= 68 && ii <= 69)
                                    {
                                        boundary.SubType = KeywordAccess;
                                    }
                                    else if (ii >= 70 && ii <= 73)
                                    {
                                        boundary.SubType = KeywordLiteral;
                                    }
                                    else if (ii >= 74 && ii <= 79)
                                    {
                                        boundary.SubType = KeywordContextual;
                                    }
                                    else if (ii >= 80 && ii <= 83)
                                    {
                                        boundary.SubType = KeywordAcesssModifier;
                                    }
                                    else if (ii >= 84)
                                    {
                                        boundary.SubType = Unsupported;
                                    }
                                    break;
                                }
                            }
                        }
                        // Add boundary
                        LBP.Add(boundary);;
                        boundary = new LexiconBoundaryPoint();
                        boundary.Start = boundary.End = -1;
                        boundary.SubType = boundary.Type = 0;
                    }
                }
            }
                #endregion
        }
        public List<LexiconBoundaryPoint> LBP;
        // Lexicon Boundary Point Types (LBPT)
        // LBP SubTypes(LBPST);
        // The types are equal the index of the array
        #region LBPTypes
        public static readonly string[] LBPTypes =
        {
            "Error",
            "Unsupported",
            "WhiteSpace",
            "WhiteSpaceLineEnding",
            "Punctuator",
            "PunctuatorCodeBlockStart",
            "PunctuatorCodeBlockEnd",
            "PunctuatorBracketStart",
            "PunctuatorBracketEnd",
            "PunctuatorSquareBracketStart",
            "PunctuatorSquareBracketEnd",
            "PunctuatorComma",
            "PunctuatorAccessor", // . or ->
            "PunctuatorColon",
            "PunctuatorColonColon", // namespace alias qualifier
            "PunctuatorSemicolon", // End of statement
            "Operator",
            "OperatorLogical",
            "OperatorBitwise",
            "OperatorMultiplicative",
            "OperatorAssignment",
            "OperatorLambda",
            "OperatorUnary",
            "OperatorConditional",
            "OperatorEquallity",
            "OperatorAddition",
            "OperatorShift",
            "OperatorTypeTesting",
            "OperatorRelational",
            "OperatorIncremental",
            "Literal",
            "LiteralString",
            "LiteralCharacter",
            "LiteralNumeric",
            "LiteralIntegerDecimal",
            "LiteralIntegerHexidecimal",
            "LiteralReal",
            "LiteralRealFloat",
            "LiteralRealDouble",
            "LiteralRealDecimal",
            "Comment",
            "CommentSingleLine",
            "CommentDelimitedLine",
            "PreProcessorDirective",
            "Keyword",
            "KeywordTypesBuiltIn",
            "KeywordTypesReferences",
            "KeywordTypeless",
            "KeywordModifiers",
            "KeywordStatementSelection",
            "KeywordStatementIteration",
            "KeywordStatementJump",
            "KeywordStatementException",
            "KeywordStatementChecked",
            "KeywordStatementFixed",
            "KeywordStatementLock",
            "KeywordMethodParameters",
            "KeywordNamespace",
            "KeywordOperators",
            "KeywordConversion",
            "KeywordAccess",
            "KeywordLiteral",
            "KeywordContextual",
            "KeywordAcesssModifier",
            "Identifier"
        };
        #endregion
        // Get the type string value by passing in the integer value
        public string WhatTypeIs(int LBPT)
        {
            /*
            if (LBPT > LBPTypes.Length || LBPT < LBPTypes.Length)
            {
                return LBPTypes[0];
            }
             */ 
            return LBPTypes[LBPT];
        }
        // Get the type index by passing in the string value
        public int WhatTypeIs(string LBPT)
        {
            for (int i = 0; i < LBPTypes.Length; i++)
            {
                if (LBPT == LBPTypes[i])
                {
                    return i;
                }
            }
            return 0;
        }
        // Find LBP In LBP List
        public int WhereIs(LexiconBoundaryPoint rLBP)
        {
            for (int i = 0; i < LBP.Count; i++)
            {
                if (
                    rLBP.Start == LBP[i].Start &&
                    rLBP.End == LBP[i].End &&
                    rLBP.Type == LBP[i].Type &&
                    rLBP.SubType == LBP[i].SubType
                    )
                {
                    return i;
                }
            }
            return -1;
        }
        // Returns the index of LBP by passing in CharacterPosition
        public int WhereIs(int CharacterPosition)
        {
            for (int i = 0; i < LBP.Count; i++)
            {
                if (
                    CharacterPosition >= LBP[i].Start &&
                    CharacterPosition <= LBP[i].End
                    )
                {
                    return i;
                }
            }
            return -1;
        }
        #region mKeywords
        private static readonly string[] mKeywords = 
        {
            //
            // Types
            // BuiltIn Types
            "bool", // i = 0
            "byte",
            "char",
            "double",
            "decimal",
            "enum",  //  integer
            "float",
            "int",
            "long",
            "sbyte",
            "short",
            "uint",
            "ulong",
            "ushort", // i = 13
            //
            // Reference Types
            "class", // i = 13
            "delegate",
            "interface",
            "object",
            "string",
            "struct", // i = 19
            // Typeless
            "void", // i = 20
            // Modifiers
            "abstract", // i = 21
            "const",
            "event",
            "extern",
            "override",
            "readonly",
            "sealed",
            "static",
            "unsafe",
            "virtual",
            "volatile", // i = 31
            //
            // Statements
            // Selection
            "if", // i = 32
            "else",
            "switch", 
            "case", // i = 35
            // Iteration
            "do", // while i = 36
            "for",
            "foreach", 
            "in",
            "while", // i = 40
            // Jump
            "break",// i = 41
            "continue",
            "goto",
            "return", // i = 44
            // Exception
            "throw", // i = 45
            "try",
            "catch",
            "finally", // i = 48
            // Checked
            "checked", // true // i = 49
            "unchecked", // false // i = 50
            // fixed
            "fixed", // i = 51
            // lock
            "lock", // i = 52
            //
            // Method Parameters
            "params", // i = 53
            "out",
            "ref", // i = 55
            //
            // Namespace
            "using", // i = 56
            "namespace",
            "alias", // extern alias // i = 58
            //
            // Operators
            "as", // i = 59
            "is",
            "new",
            "sizeof",
            "typeof",
            "stackalloc", // i = 64
            //
            // Conversion
            "explicit",// i = 65
            "implicit",
            "operator", // i = 67
            //
            // Access
            "base", // i = 68
            "this", // i = 69
            //
            // Literal
            "true", // i = 70
            "false",
            "null",
            "default", // i = 73
            //
            // Contextual
            "get", // i = 74
            "partial",
            "set",
            "value",
            "where", 
            "yield", // i = 79
            // Access Modifier
            "public", // 80
            "private",
            "protected",
            "internal", // 83
            // Unsupported
            "dynamic",
            "var",
            "async",
            "await",
            "add",
            "global",
            "remove"
        };
        #endregion
    }
}
